package com.pengxh.app.gb28181.util;

public class ByteArrayHelper {
    /**
     * 镜像NV21格式数据（水平翻转）
     *
     * @param data   NV21数据
     * @param width  宽度
     * @param height 高度
     * @return 镜像后的数据
     */
    public static byte[] mirrorNV21(byte[] data, int width, int height) {
        byte[] output = new byte[data.length];
        int ySize = width * height;

        // 镜像Y分量
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                output[y * width + x] = data[y * width + (width - x - 1)];
            }
        }

        // 镜像UV分量 (NV21格式: YYYY...VVUU...)
        for (int y = 0; y < height / 2; y++) {
            for (int x = 0; x < width / 2; x++) {
                int srcPos = ySize + y * width + x * 2;
                int destPos = ySize + y * width + (width / 2 - x - 1) * 2;
                output[destPos] = data[srcPos];         // V
                output[destPos + 1] = data[srcPos + 1]; // U
            }
        }

        return output;
    }

    /**
     * 转换NV21格式数据为NV12格式，应编码器常接受 NV12 格式作为输入
     *
     * @param nv21   NV21数据
     * @param width  宽度
     * @param height 高度
     * @return 转换后的数据
     */
    public static byte[] convertToNV12(byte[] nv21, int width, int height) {
        byte[] nv12 = new byte[nv21.length];

        int ySize = width * height;
        int uSize = ySize / 4;

        // Y分量直接复制
        System.arraycopy(nv21, 0, nv12, 0, ySize);

        // U和V分量交换位置
        for (int i = 0; i < uSize; i++) {
            nv12[ySize + 2 * i] = nv21[ySize + 2 * i + 1]; // V
            nv12[ySize + 2 * i + 1] = nv21[ySize + 2 * i]; // U
        }

        return nv12;
    }

    /**
     * 旋转NV21格式数据90度
     *
     * @param data   NV21数据
     * @param width  宽度
     * @param height 高度
     * @return 旋转后的数据
     */
    public static byte[] rotateNV21_90(byte[] data, int width, int height) {
        byte[] output = new byte[data.length];
        int ySize = width * height;

        // 旋转Y分量
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                output[x * height + (height - y - 1)] = data[y * width + x];
            }
        }

        // 旋转UV分量
        for (int y = 0; y < height / 2; y++) {
            for (int x = 0; x < width / 2; x++) {
                int srcPos = ySize + y * width + x * 2;
                int destPos = ySize + x * height + (height / 2 - y - 1) * 2;
                output[destPos] = data[srcPos];         // V
                output[destPos + 1] = data[srcPos + 1]; // U
            }
        }

        return convertToNV12(output, height, width);
    }

    /**
     * 旋转NV21格式数据180度
     *
     * @param data   NV21数据
     * @param width  宽度
     * @param height 高度
     * @return 旋转后的数据
     */
    public static byte[] rotateNV21_180(byte[] data, int width, int height) {
        byte[] output = new byte[data.length];
        int ySize = width * height;
        int uvSize = ySize / 2;

        // 旋转Y分量
        for (int i = 0; i < ySize; i++) {
            output[ySize - i - 1] = data[i];
        }

        // 旋转UV分量
        for (int i = 0; i < uvSize; i += 2) {
            output[data.length - i - 2] = data[ySize + i];     // V
            output[data.length - i - 1] = data[ySize + i + 1]; // U
        }

        return convertToNV12(output, width, height);
    }

    /**
     * 旋转NV21格式数据270度
     *
     * @param data   NV21数据
     * @param width  宽度
     * @param height 高度
     * @return 旋转后的数据
     */
    public static byte[] rotateNV21_270(byte[] data, int width, int height) {
        byte[] output = new byte[data.length];
        int ySize = width * height;

        // 旋转Y分量
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                output[(width - x - 1) * height + y] = data[y * width + x];
            }
        }

        // 旋转UV分量
        for (int y = 0; y < height / 2; y++) {
            for (int x = 0; x < width / 2; x++) {
                int srcPos = ySize + y * width + x * 2;
                int destPos = ySize + (width / 2 - x - 1) * height + y * 2;
                output[destPos] = data[srcPos];         // V
                output[destPos + 1] = data[srcPos + 1]; // U
            }
        }

        return convertToNV12(output, height, width);
    }
}
